#ifndef IMAGEANNOTATION_H
#define IMAGEANNOTATION_H

#include <string>
#include <vector>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <algorithm>
#include "QFile"
#include "QXmlStreamWriter"
#include "QIODevice"
#include "imageannitem.h"
#include "annotationimage.h"
#include "imageannentry.h"
#include "utility.h"

using namespace std;

class AnnotationImage;

// 表示图像的所有标注，包含标注的图像文件名、图像中标注项数量等。
class ImageAnnotation
{
public:
    /*-----------------构造函数----------------*/
    // 默认构造函数
    ImageAnnotation() = default;
    // 接收三个参数的构造函数
    ImageAnnotation(string imgName, string annName, AnnotationImage * p) : imageFileName(imgName), annFileName(annName), pAnnImage(p), annEntryCounts(0) { read(); }

    /*-----------------成员函数----------------*/
    // 读入标注内容
    bool read();

    // 写入标注内容到文件
    bool write();

    // 添加标注项
    void Add(const ImageAnnEntry &annItem);

    // 删除标注项
    void Remove(const ImageAnnEntry &annItem);

    // 清空标注项
    void clear();

    /*----------------getter-----------------*/
    // 得到当前图片的所有标注数据
    const vector<ImageAnnEntry>& getImageEntries() const
    {
        return imageAnnEntries;
    }
    vector<ImageAnnEntry>& getImageEntries()
    {
        return imageAnnEntries;
    }

    // 得到当前图片的标注数量
    int getAnnEntryCounts() const
    {
        return annEntryCounts;
    }

    // 得到当前标注图片文件名
    const string& getImageFileName() const
    {
        return imageFileName;
    }

    // 得到标注数据的文件名
    const string& getAnnFileName() const
    {
        return annFileName;
    }

    // 得到当前标注的图像的实例指针
    AnnotationImage * getPAnnImage()
    {
        return pAnnImage;
    }

    /*----------------setter-----------------*/
    // 设置当前图片的所有标注条目数据
    void setImageEntries(const vector<ImageAnnEntry> &data)
    {
        imageAnnEntries = data;
    }

    // 设置当前图片的标注数量
    void setAnnItemCounts(int n)
    {
        annEntryCounts = n;
    }

    // 设置标注的图片文件名
    void setImageFileName(const string &f)
    {
        imageFileName = f;
    }

    // 设置标注数据文件名
    void setAnnFileName(const string &f)
    {
        annFileName = f;
    }

    // 设置当前标注图像的实例指针
    void setPAnnImage(AnnotationImage * p)
    {
        pAnnImage = p;
    }


private:
    // 当前图片的全部标注项
    vector<ImageAnnEntry> imageAnnEntries;

    // 当前图片的标注条目数量
    int annEntryCounts;

    // 当前标注图片文件名
    string imageFileName;

    // 标注数据文件名
    string annFileName;

    // 标注图像实例指针
    AnnotationImage * pAnnImage;

    // 将标注写到xml文件
    bool write2xml();

    // 将标注写到dat文件
    bool write2dat();

    // 从dat文件中读取标注数据
    bool readFromDat();
};

#endif // IMAGEANNOTATION_H
